package com.itzhoun;

/**
 * @author 周楠
 * @Date 2023/01/14/下午 5:07
 */
public class PrototypeTest {


    /**
     * 原型模式（Prototype Pattern）是用于创建重复的对象，同时又能保证性能。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。
     *
     * 这里采用两种方式比较 第1种传统方式  第2种原型模式
     *
     * 浅复制：将一个对象复制后，基本数据类型的变量都会重新创建，而引用类型，指向的还是原对象所指向的。
     *
     * 深复制：将一个对象复制后，不论是基本数据类型还有引用类型，都是重新创建的。简单来说，就是深复制进行了完全彻底的复制，而浅复制不彻底。clone明显是深复制，clone出来的对象是是不能去影响原型对象的
     *
     *
     *
     */


    public static void main(String[] args) throws CloneNotSupportedException {

        /**
         * 传统方式
         * 优点： 比较好理解
         * 缺点：在创建新的对象时，总是需要重新获取原始对象的属性，如果创建的对象比较复杂时，效率较低
         * 总是需要重新初始化对象，而不是动态地获得对象运行时的状态，不够灵活
         */

//        Sheep sheep = new Sheep("tom", 1, "白色");
//        Sheep sheep1 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());

        /**
         * 原型模式
         *
         * 创建新的对象比较复杂时，可以利用原型模式简化对象的创建过程，同时也能够提高效率
         * 不用重新初始化对象，而是动态地获得对象运行时的状态
         * 如果原始对象发生变化(增加或者减少属性)，其它克隆对象的也会发生相应的变化，无需修改代码
         * 在实现深克隆的时候可能需要比较复杂的代码
         *
         * 缺点:需要为每一个类配备一个克隆方法，这对全新的类来说不是很难，但对已有的类进行改造时，需要修改其源代码，违背了ocp原则
         */


        /**
         * 浅拷贝 重写了clone方法
         */
        Sheep sheep2 = new Sheep("tom", 1, "白色");
        System.out.println("sheep2的hashCode" + sheep2.hashCode());
        sheep2.cloneSheep = new Sheep("jack", 2 ,"黑色");
        System.out.println("sheep2的朋友的hashCode为" + sheep2.cloneSheep.hashCode());


        Sheep sheep3 = (Sheep)sheep2.clone();
        System.out.println("sheep3的hashCode为" + sheep3.hashCode());


        Sheep sheep4 = (Sheep)sheep2.clone();
        System.out.println("sheep4的hashCode为" + sheep4.hashCode());


        //地址一样，采用了clone浅拷贝引用了原来的hashCode值
        System.out.println("sheep3" + sheep3 + "sheep3 的朋友" + sheep3.cloneSheep.hashCode());
        System.out.println("sheep4" + sheep4 + "sheep4 的朋友" + sheep4.cloneSheep.hashCode());


        /**
         * 深拷贝 新增deepClone方法
         */
        Sheep sheep = new Sheep("tom", 1, "白色");
        System.out.println("sheep的hashCode" + sheep.hashCode());

        sheep.cloneSheep = new Sheep("jack", 2 ,"黑色");
        System.out.println("sheep朋友hashCode值" + sheep.cloneSheep.hashCode());

        Sheep sheep5 = (Sheep)sheep.deepClone();

        Sheep sheep6 = (Sheep)sheep.deepClone();

        //深拷贝 hashCode不一样了
        System.out.println("sheep5" + sheep5 + "sheep5 的hashCode" + sheep5.cloneSheep.hashCode());
        System.out.println("sheep6" + sheep6 + "sheep6 的hashCode" + sheep6.cloneSheep.hashCode());


    }
}
